/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   IceTransport.h
 * Author: user
 *
 * Created on June 5, 2017, 9:51 AM
 */

#ifndef ICETRANSPORT_H
#define ICETRANSPORT_H

#include <stdio.h>
#include <stdlib.h>

extern "C" {
#include <pjlib.h>
#include <pjlib-util.h>
#include <pjnath.h>
}

#define THIS_FILE   __FILE__

#define KA_INTERVAL 300

class IceTransport {
public:
    IceTransport();
    IceTransport(const IceTransport& orig);
    virtual ~IceTransport();

    void setOptions();
    void setRole(unsigned role);
    void setName(char* name);

    bool init();
    bool deinit();

    bool start();
    bool stop();

    void startNegotiation(void);

    void showIceInfo(void);
    int getLocalSDP(char* buffer, unsigned maxlen);
    void setRemoteSDP(char* buffer);
    void sendData(unsigned comp_id, const char *data);

    /* options are stored here */
    struct options {
        unsigned comp_cnt;
        pj_str_t ns;
        int max_host;
        pj_bool_t regular;
        pj_str_t stun_srv;
        pj_str_t turn_srv;
        pj_bool_t turn_tcp;
        pj_str_t turn_username;
        pj_str_t turn_password;
        pj_bool_t turn_fingerprint;
        const char *log_file;
    } opt;

    /* Variables to store parsed remote ICE info */
    struct rem_info {
        char ufrag[80];
        char pwd[80];
        unsigned comp_cnt;
        pj_sockaddr def_addr[PJ_ICE_MAX_COMP];
        unsigned cand_cnt;
        pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND];
    } rem;

    pj_ice_strans_cfg ice_cfg;
    pj_ice_strans *icest;
    pj_bool_t thread_quit_flag;
    
    char name[80];

private:
    static int workerThread(void *data);
    static pj_status_t handleEevents(unsigned max_msec, unsigned *p_count, IceTransport* instance);
    static void onReceiveData(pj_ice_strans *ice_st,
            unsigned comp_id,
            void *pkt, pj_size_t size,
            const pj_sockaddr_t *src_addr,
            unsigned src_addr_len);
    static void onIceComplete(pj_ice_strans *ice_st,
            pj_ice_strans_op op,
            pj_status_t status);
    void resetRemoteInfo(void);
    int printCandidate(char buffer[], unsigned maxlen,
            const pj_ice_sess_cand *cand);
    int getALine(char* line, char* buffer, int startPos);
    int encodeSessionInfo(char* buffer, unsigned maxlen);
    void printError(const char *title, pj_status_t status);

    void createInstance(void);
    void destroyInstance(void);
    void initSession(unsigned rolechar);
    void stopSession(void);

    unsigned role;
    pj_caching_pool cp;
    pj_pool_t *pool;

    pj_thread_t *thread;

};

#endif /* ICETRANSPORT_H */

